package com.atguigu.gulimall.order.controller;

import com.atguigu.gulimall.order.entity.OrderEntity;
import com.atguigu.gulimall.order.entity.OrderReturnReasonEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.UUID;

@RestController
@Slf4j
public class RabbitController{

    @Resource
    RabbitTemplate rabbitTemplate;

    @GetMapping("/send/{num}")
    public String sendRabbitMsg(@PathVariable(value = "num") Integer num){
        OrderReturnReasonEntity orderReturnReasonEntity = new OrderReturnReasonEntity();
        orderReturnReasonEntity.setCreateTime(new Date());
        orderReturnReasonEntity.setId(1L);
        orderReturnReasonEntity.setName("很好");
        orderReturnReasonEntity.setSort(1);
        orderReturnReasonEntity.setStatus(1);
        for(int i = 0;i<num;i++){
            if(i%2==0){
                rabbitTemplate.convertAndSend("hello-java-exchange","hello java",orderReturnReasonEntity,new CorrelationData(UUID.randomUUID().toString()));
            }else {
                OrderEntity orderEntity = new OrderEntity();
                orderEntity.setId(Long.parseLong(""+i));
                rabbitTemplate.convertAndSend("hello-java-exchange","hello java",orderEntity,new CorrelationData(UUID.randomUUID().toString()));
            }
              log.info("消息{}发送成功 {}",i,orderReturnReasonEntity);
        }
        return "ok";
    }

    /**
     * 1. rabbitMq  服务器收到消息就回调
     * spring.rabbitmq.publisher-confirms=true
     *
     * 2. 消息正确抵达队列惊醒回调
     *      1.spring.rabbitmq.publisher-returns=true
     *      2.spring.rabbitmq.template.mandatory=true
     *
     * 3. 消费端确认。 保证每一个消息都被消费
     *      1、默认事自动确认，只要消息接收到，
     *      2. 手动确认   。  只要我们没有明确告诉MQ ,货物被签收（ 没有ACK）  消息一直是 unacked 状态， 即使 consumer 宕机，
     *      会重新变为ready, 下一次comsumer 进来再来一次ack
     */
    @PostConstruct
    public void initRabbitTemplate(){
        //设置确认回调
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("confirm...correlationData=["+correlationData+"]");
                System.out.println("confirm...ack=["+ack+"]");
                System.out.println("confirm...cause=["+cause+"]");
            }
        });
        // 设置消息抵达队列确认回调

        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            /**
             * 只要消息没有投递给指定得队列，就触发这个失败回调
             * @param message   投递失败得消息详细信息
             * @param replyCode  回复得状态码
             * @param replyText  回复得文本内容
             * @param exchange   当时消息发给哪个交换机
             * @param routingKey  指定得路由键
             */
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                System.out.println("Fail Message"+message);
                System.out.println("Fail Message"+replyCode);
                System.out.println("Fail Message"+replyText);
                System.out.println("Fail Message"+exchange);
                System.out.println("Fail Message"+routingKey);
            }
        });
    }
}
